package showgo.modell;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.DateFormat;
import java.text.Format;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.JOptionPane;

import showgo.gui.IMyListener;
import showgo.gui.PseudoRollenDialog;
import showgo.gui.RollenDialog;
import showgo.modell.inszenierung.Darstellerposten;
import showgo.modell.inszenierung.Inszenierung;
import showgo.modell.inszenierung.Nichtdarstellerposten;
import showgo.modell.stamm.Ensemble;
import showgo.modell.stamm.Person;
import showgo.modell.stueck.Absatz;
import showgo.modell.stueck.Akt;
import showgo.modell.stueck.Rede;
import showgo.modell.stueck.Regieanweisung;
import showgo.modell.stueck.Rolle;
import showgo.modell.stueck.Stueck;
import showgo.modell.stueck.Szene;
import showgo.modell.stueck.Text;

/**
 * @author lutz Dies ist die zentrale Klasse fuer alle Methoden, die mehrere
 *         Klassen steuern bzw. die von mehreren Klassen verwendet werden;
 */
public class Manager {

    // Pfad der geladenen Datei
    private String loadedFilePath;

    private static Manager instance = null;

    private String gesamtesStueck;
    
    private List<String> nichtDarstellerPosten=new ArrayList<String>();
    
    public void initNichtDarstellerPosten(){
	nichtDarstellerPosten.add("Regie");
	nichtDarstellerPosten.add("Regieassistenz");
	nichtDarstellerPosten.add("Kostueme");
	nichtDarstellerPosten.add("Requisite");
	nichtDarstellerPosten.add("Buehnenbild");
	nichtDarstellerPosten.add("Techniker");
	nichtDarstellerPosten.add("Helfer");
    }
    
    private Set<IMyListener> listeners = new HashSet<IMyListener>();

    private List<Ensemble> ensembles = new ArrayList<Ensemble>();

    private List<Inszenierung> inszenierungen = new ArrayList<Inszenierung>();

    private List<Stueck> stuecke = new ArrayList<Stueck>();

    private List<Rolle> rollenImStueck = new ArrayList<Rolle>();

    public List<Rolle> getRollenImStueck() {
	return rollenImStueck;
    }

    public void setRollenImStueck(List<Rolle> rollenImStueck) {
	this.rollenImStueck = rollenImStueck;
    }

    private List<Person> personen = new ArrayList<Person>();

    public List<Stueck> getStuecke() {
	return stuecke;
    }

    public List<Person> getPersonen() {
	return personen;
    }

    public void setPersonen(List<Person> personen) {
	this.personen = personen;
    }

    public String getLoadedFilePath() {
	return loadedFilePath;
    }

    public void setLoadedFilePath(String loadedFilePath) {
	this.loadedFilePath = loadedFilePath;
    }

    /**
     * @return sorgt dafuer, dass max. eine Instanz der Manager-Klasse
     *         existiert;
     */
    public synchronized static Manager getInstance() {
	if (instance == null) {
	    instance = new Manager();
	}
	return instance;
    }

    /**
     * @param path
     *            Diese Methode laedt das Stueck aus dem uebergebenen Pfad;
     */
    public void ladeStueck(String path) {
	if (path != null) {
	    this.loadedFilePath = path;
	    try {
		BufferedReader br = new BufferedReader(new InputStreamReader(
			new FileInputStream(loadedFilePath)));
		String zeile;
		gesamtesStueck = "";
		// beim zeilenweisen Einlesen der Datei
		// wird ein langer String erzeugt
		while ((zeile = br.readLine()) != null) {
		    gesamtesStueck += zeile.trim();
		}
		br.close();
	    } catch (FileNotFoundException e) {
		e.printStackTrace();
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	    // Theaterstueck aus dem langen String parsen:
	    Stueck neuesStueck = parseStueck(gesamtesStueck);
	    // allen Rollen im Stueck Alter und Geschlecht zuordnen:
	    erweitereRollen(neuesStueck);

	    List<Rolle> finaleRollen = new ArrayList<Rolle>();
	    for (int i = 0; i < rollenImStueck.size(); i++) {
		finaleRollen.add(rollenImStueck.get(i).tiefeKopie());
	    }
	    neuesStueck.setRollen(finaleRollen);
	    rollenImStueck.clear();
	    fuegeStueckHinzu(neuesStueck);
	    fireListChanged();
	}
    }

    /**
     * @param titel
     *            Entfernen eines Theaterstueckes aus der List anhand des
     *            uebergebenen Titels
     */
    public void entferneStueck(String titel) {
	if (!this.stuecke.isEmpty()) {
	    for (int i = 0; i < stuecke.size(); i++) {
		if (stuecke.get(i).getName().equals(titel)) {
		    stuecke.remove(i);
		}
	    }
	}
	fireListChanged();
    }

    /**
     * @param s
     * @return Der uebergebene String stellt das eingelesene Theaterstueck aus
     *         der HTML-Datei da; Diese Methode zerlegt den String in den Titel
     *         und die jeweiligen Akte;
     */
    private Stueck parseStueck(String s) {
	if (s != null) {
	    // Titel extrahieren:
	    String titel = s.substring(
		    s.indexOf("<title>") + "<title>".length(),
		    s.indexOf("</title>"));

	    // parse stueck
	    int start = s.indexOf("<!--stueck-->") + "<!--stueck-->".length();
	    int end = s.indexOf("<!--/stueck-->");
	    s = s.substring(start, end);

	    List<Akt> akte = new ArrayList<Akt>();
	    // alle Akte anhand der Signatur "<!--aufzug-->" finden und parsen:
	    while (s.indexOf("<!--aufzug-->") >= 0) {
		start = s.indexOf("<!--aufzug-->") + "<!--aufzug-->".length();
		end = s.indexOf("<!--/aufzug-->");

		String aktString = s.substring(start, end);
		// den extrahierten Akt parsen:
		Akt akt = parseAkt(aktString);
		akte.add(akt);

		s = s.substring(end + "<!--/aufzug-->".length());
	    }
	    Stueck stueck = new Stueck(titel, akte, rollenImStueck);
	    // Finden und Bearbeiten von Pseudorollen:
	    findePseudorRollenImStueck(stueck);

	    return stueck;
	}
	return null;
    }

    /**
     * @param aktString
     * @return Der uebergebene String stellt einen Akt im Stueck dar; Diese
     *         Methode extrahiert alle Szenen daraus und parst sie;
     */
    private Akt parseAkt(String aktString) {
	if (aktString != null) {
	    // Akt-ID extrahieren
	    String aktID = aktString.substring(
		    aktString.indexOf("<!--aufzug-->") + 1,
		    aktString.indexOf("<!--szene-->"));

	    // unnoetige Zeichen aus Akt-ID entfernen
	    while (aktID.contains("<br>")) {
		aktID = aktID.replace("<br>", "");
	    }
	    aktID = aktID.replace(".", "");

	    List<Szene> szenen = new ArrayList<Szene>();
	    // Szenen anhand der Signatur "<!--szene-->" finden und parsen:
	    while (aktString.indexOf("<!--szene-->") >= 0) {
		int start = aktString.indexOf("<!--szene-->")
			+ "<!--szene-->".length();
		int end = aktString.indexOf("<!--/szene-->");

		String szeneString = aktString.substring(start, end);
		Szene szene = parseSzene(aktID, szeneString);
		szenen.add(szene);

		aktString = aktString.substring(end + "<!--/szene-->".length());
	    }
	    Akt akt = new Akt(new String(aktID), szenen);
	    return akt;
	}
	return null;
    }

    /**
     * @param aktID
     * @param szeneString
     * @return Der uebergebne String stellt eine Szene dar; Diese Methode parst
     *         diese Szene;
     */
    private Szene parseSzene(String aktID, String szeneString) {
	if (szeneString != null) {
	    // Szenen-ID extrahieren:
	    String szenenID = szeneString.substring(
		    szeneString.indexOf("<!--szene-->") + 1,
		    szeneString.indexOf("<"));
	    szenenID = szenenID.replace(".", "");

	    List<Rolle> rollenInSzene = new ArrayList<Rolle>();
	    List<Absatz> absaetze = new ArrayList<Absatz>();
	    String rollenName = "";
	    for (int i = 0; i < szeneString.length() - 4; i++) {

		// falls Regieanweisung
		String anweisung = "";
		if (String.valueOf(szeneString.charAt(i)).equals("-")
			&& String.valueOf(szeneString.charAt(i + 1))
				.equals("r")
			&& String.valueOf(szeneString.charAt(i + 2))
				.equals("e")) {
		    i += 9;
		    while (!String.valueOf(szeneString.charAt(i)).equals("!")) {
			anweisung += szeneString.charAt(i);
			i++;
		    }
		    anweisung = anweisung.replaceFirst("<br><br>", "");
		    anweisung = anweisung.replaceAll("<br>", " ");
		    anweisung = anweisung.replaceAll("<", "");
		    Regieanweisung regieAnweisung = new Regieanweisung(
			    "Regieanweisung", anweisung);
		    absaetze.add(regieAnweisung);
		} else if (String.valueOf(szeneString.charAt(i)).equals("-")
			&& String.valueOf(szeneString.charAt(i + 1))
				.equals("p")
			&& String.valueOf(szeneString.charAt(i + 11)).equals(
				"<")) {
		    // dann ist neue Rolle dran
		    String text = "";
		    i += 12;

		    while (!(String.valueOf(szeneString.charAt(i)).equals("/") && String
			    .valueOf(szeneString.charAt(i + 1)).equals("p"))) {
			if (String.valueOf(szeneString.charAt(i)).equals("-")
				&& String.valueOf(szeneString.charAt(i + 1))
					.equals("r")
				&& String.valueOf(szeneString.charAt(i + 2))
					.equals("o")) {
			    i += 9;
			    rollenName = "";
			    while (!String.valueOf(szeneString.charAt(i))
				    .equals("<")) {
				rollenName += szeneString.charAt(i);
				i++;
			    }
			    while (!String.valueOf(szeneString.charAt(i))
				    .equals(">")) {
				i++;
			    }
			    i += 1;
			    while (!String.valueOf(szeneString.charAt(i + 1))
				    .equals("/")) {
				text += szeneString.charAt(i);
				i++;
			    }
			}
			i++;
		    }
		    text = text.replaceFirst("<br>", "");
		    text = text.replaceAll("<br><br>", " ");
		    text = text.replaceAll("<br>", "");
		    text = text.replaceAll("<!-", "");
		    if (String.valueOf(
			    rollenName.charAt(rollenName.length() - 1)).equals(
			    ".")
			    || String.valueOf(
				    rollenName.charAt(rollenName.length() - 1))
				    .equals(" ")) {
			rollenName = rollenName.substring(0,
				rollenName.length() - 1);
		    }

		    if (text.length() < 1) {

		    } else {
			Rede rede = new Rede("Redepassage", rollenName,
				new Text(text));
			absaetze.add(rede);
		    }

		    if (rollenInSzene.isEmpty()) {
			int textMenge = new Text(text).zaehleWoerter();
			Rolle rolle = new Rolle(rollenName, 0, "unbekannt",
				textMenge);
			rollenInSzene.add(rolle);
		    } else if (rolleIstSchonVorhanden(rollenName, rollenInSzene)) {
			for (int j = 0; j < rollenInSzene.size(); j++) {
			    if (rollenInSzene.get(j).getRollenName()
				    .equals(rollenName)) {
				rollenInSzene.get(j).setTextMenge(
					rollenInSzene.get(j).getTextMenge()
						+ new Text(text)
							.zaehleWoerter());
			    }
			}
		    } else {
			int textMenge = new Text(text).zaehleWoerter();
			Rolle rolle = new Rolle(rollenName, 0, "unbekannt",
				textMenge);
			rollenInSzene.add(rolle);
		    }
		} else if (String.valueOf(szeneString.charAt(i)).equals("-")
			&& String.valueOf(szeneString.charAt(i + 1))
				.equals("p")
			&& !String.valueOf(szeneString.charAt(i + 11)).equals(
				"<")) {
		    // dann keine neue Rolle und folgender Text zur Rolle davor
		    String text = "";
		    i += 10;
		    while (!(String.valueOf(szeneString.charAt(i)).equals("/") && String
			    .valueOf(szeneString.charAt(i + 1)).equals("p"))) {
			text += szeneString.charAt(i);
			i++;
		    }
		    text = text.replaceFirst("<br>", "");
		    text = text.replaceAll("<br><br>", " ");
		    text = text.replaceAll("<br>", "");
		    text = text.replaceAll("<!--", "");
		    text = text.replaceAll("<!-", "");
		    text = text.replaceAll(">", "");

		    Rede rede = new Rede("Redepassage", rollenName, new Text(
			    text));
		    absaetze.add(rede);
		}
	    }
	    Szene szene = new Szene(szenenID, rollenInSzene, absaetze);
	    return szene;
	}
	return null;
    }

    public void editiereRolle(Rolle rolle) {
	// uebergebene Rolle finden
	if (!rollenImStueck.isEmpty()) {
	    for (int i = 0; i < rollenImStueck.size(); i++) {
		if (rollenImStueck.get(i).getRollenName()
			.equals(rolle.getRollenName())) {
		    // neue Werte aus RollenDialog setzen
		    rollenImStueck.get(i).setAlter(rolle.getAlter());
		    rollenImStueck.get(i).setGeschlecht(rolle.getGeschlecht());
		}
	    }
	}
    }

    /**
     * @param stueck
     *            nach dem Parsen des Stuecks wird der Rollendialog geoeffnet,
     *            indem den Rollen Alter und Geschlecht zugeordnet werden kann;
     */
    private void erweitereRollen(Stueck stueck) {
	final RollenDialog rollenDialog = new RollenDialog(stueck);
	rollenDialog.setLocationRelativeTo(null);
	rollenDialog.setModal(true);
	rollenDialog.setVisible(true);
    }

    private boolean rolleIstSchonVorhanden(String name, List<Rolle> rollen) {
	if (name != null && !rollen.isEmpty()) {
	    for (int j = 0; j < rollen.size(); j++) {
		if (rollen.get(j).getRollenName().equals(name)) {
		    return true;
		}
	    }
	}
	return false;
    }

    /**
     * @param stueck
     *            Diese Methode findet Pseudorollen im Theaterstueck anhand von
     *            bestimmten Zeichenfolgen wie "ALLE"; Wird so eine Pseudorolle
     *            gefunden, wird der Dialog zum Aufloesen der Pseudorollen
     *            geoffnet;
     */
    private void findePseudorRollenImStueck(Stueck stueck) {
	List<Akt> akte = stueck.getAkte();
	for (int i = 0; i < akte.size(); i++) {
	    for (int j = 0; j < akte.get(i).getSzenen().size(); j++) {

		// fuer alle Rollen in einer Szene suche Rolle "Alle":
		int textMengeAlle = 0;
		for (int k = 0; k < akte.get(i).getSzenen().get(j)
			.getRollenInSzene().size(); k++) {
		    if (akte.get(i).getSzenen().get(j).getRollenInSzene()
			    .get(k).getRollenName().equals("ALLE")
			    || akte.get(i).getSzenen().get(j)
				    .getRollenInSzene().get(k).getRollenName()
				    .equals("alle")
			    || akte.get(i).getSzenen().get(j)
				    .getRollenInSzene().get(k).getRollenName()
				    .equals("Alle")) {
			// Textmenge dieser Pseudorolle holen
			textMengeAlle = akte.get(i).getSzenen().get(j)
				.getRollenInSzene().get(k).getTextMenge();

			// Pseudorolle "ALLE" entfernen
			akte.get(i).getSzenen().get(j).getRollenInSzene()
				.remove(k);
			k--;
		    }
		}

		// Text-Menge auf die restlichen Rollen addieren
		for (int k = 0; k < akte.get(i).getSzenen().get(j)
			.getRollenInSzene().size(); k++) {
		    akte.get(i)
			    .getSzenen()
			    .get(j)
			    .getRollenInSzene()
			    .get(k)
			    .setTextMenge(
				    textMengeAlle
					    + akte.get(i).getSzenen().get(j)
						    .getRollenInSzene().get(k)
						    .getTextMenge());
		}

		List<Rolle> pseudoRollenInSzene = new ArrayList<Rolle>();

		for (int k = 0; k < akte.get(i).getSzenen().get(j)
			.getRollenInSzene().size(); k++) {
		    // suche Pseudorollen
		    if (akte.get(i).getSzenen().get(j).getRollenInSzene()
			    .get(k).getRollenName().contains(",")) {
			// Hinzufuegen zu Array
			fuegePseudorolleHinzu(akte.get(i).getSzenen().get(j)
				.getRollenInSzene().get(k), pseudoRollenInSzene);
		    }
		    if (akte.get(i).getSzenen().get(j).getRollenInSzene()
			    .get(k).getRollenName().contains(" UND")) {
			fuegePseudorolleHinzu(akte.get(i).getSzenen().get(j)
				.getRollenInSzene().get(k), pseudoRollenInSzene);
		    }
		    if (akte.get(i).getSzenen().get(j).getRollenInSzene()
			    .get(k).getRollenName().contains("ALLE")
			    || akte.get(i).getSzenen().get(j)
				    .getRollenInSzene().get(k).getRollenName()
				    .contains("alle")) {
			fuegePseudorolleHinzu(akte.get(i).getSzenen().get(j)
				.getRollenInSzene().get(k), pseudoRollenInSzene);
		    }
		}

		// Pseudorollen aufloesen, falls vorhanden
		if (pseudoRollenInSzene.size() > 0) {
		    PseudoRollenDialog pseudoRollenDialog = new PseudoRollenDialog(
			    pseudoRollenInSzene, akte.get(i).getSzenen().get(j)
				    .getRollenInSzene(), new String(akte.get(i)
				    .getAktID()
				    + " - "
				    + akte.get(i).getSzenen().get(j)
					    .getSzenenID()), stueck);
		    pseudoRollenDialog.setModal(true);
		    pseudoRollenDialog.setVisible(true);
		}
		// Rollen aller Szenen zu den Rollen des Stueckes laden
		for (int k = 0; k < akte.get(i).getSzenen().get(j)
			.getRollenInSzene().size(); k++) {

		    Rolle neueRolle = akte.get(i).getSzenen().get(j)
			    .getRollenInSzene().get(k);

		    if (rolleIstSchonVorhanden(neueRolle.getRollenName(),
			    this.rollenImStueck)) {
			for (int l = 0; l < this.rollenImStueck.size(); l++) {
			    if (this.rollenImStueck.get(l).getRollenName()
				    .equals(neueRolle.getRollenName())) {
				this.rollenImStueck.get(l).setTextMenge(
					this.rollenImStueck.get(l)
						.getTextMenge()
						+ neueRolle.getTextMenge());
			    }
			}
		    } else {
			this.rollenImStueck.add(neueRolle);
		    }
		}
		// Textmenge auf volle Zehner aufrunden
		for (int k = 0; k < this.rollenImStueck.size(); k++) {
		    int x = this.rollenImStueck.get(k).getTextMenge();
		    this.rollenImStueck.get(k).setTextMenge(10 - (x % 10) + x);
		}
	    }
	}
    }

    private void fuegePseudorolleHinzu(Rolle pseudoRolle,
	    List<Rolle> pseudoRollenInSzene) {
	if (!pseudoRollenInSzene.contains(pseudoRolle)) {
	    pseudoRollenInSzene.add(pseudoRolle);
	}
    }

    /**
     * @param target
     * @param temp
     *            Diese Methode ist zur Persistierung aller Daten
     *            verantwortlich; Die Daten werden im ASCII-Code gespeichert;
     */
    public void schreibeProjektInDatei(File target, boolean temp) {
	try {
	    // Das Dokument mit den Daten fuer ShowGO hat eine
	    // "nicht-standard" Endung!
	    // Somit soll verhindert werden, dass Personen mit wenig PC-
	    // Kenntnissen diese Datei editieren koennen.
	    String filename = target.getAbsolutePath();
	    filename += filename.endsWith(".nnn") ? "" : ".nnn";
	    filename += temp ? ".tmp" : "";
	    File file = new File(filename);

	    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
		    new FileOutputStream(file)));

	    // allgemeine Infos schreiben
	    Calendar calendar = new GregorianCalendar();
	    Format format = DateFormat.getDateTimeInstance(DateFormat.LONG,
		    DateFormat.LONG);
	    Date date = calendar.getTime();

	    writer.write("ShowGO - Daten; Stand: " + format.format(date));
	    writer.newLine();
	    // Stuecke
	    writer.write("Stuecke");
	    if (!stuecke.isEmpty()) {
		for (int i = 0; i < stuecke.size(); i++) {
		    writer.newLine();
		    writer.write("Stueck");
		    // Titel des Stueckes schreiben
		    writer.newLine();
		    writer.write("Titel");
		    writer.newLine();
		    writer.write(stuecke.get(i).getName());
		    writer.newLine();
		    writer.write("!Titel");
		    // Akte schreiben
		    if (!stuecke.get(i).getAkte().isEmpty()) {
			writer.newLine();
			// fuer jeden Aufzug im Stueck
			for (int j = 0; j < stuecke.get(i).getAkte().size(); j++) {
			    Akt currentAkt = stuecke.get(i).getAkte().get(j);
			    if (j > 0) {
				writer.newLine();
			    }
			    writer.write("Aufzug");
			    writer.newLine();
			    writer.write(currentAkt.getAktID().trim());

			    if (!currentAkt.getSzenen().isEmpty()) {
				writer.newLine();
				// fuer jede Szene eines Aktes
				for (int k = 0; k < currentAkt.getSzenen()
					.size(); k++) {
				    if (k > 0) {
					writer.newLine();
				    }
				    Szene currentSzene = currentAkt.getSzenen()
					    .get(k);
				    writer.write("Szene");
				    writer.newLine();
				    writer.write(currentSzene.getSzenenID()
					    .trim());

				    if (!currentSzene.getAbsaetze().isEmpty()) {
					writer.newLine();
					for (int l = 0; l < currentSzene
						.getAbsaetze().size(); l++) {
					    if (l > 0) {
						writer.newLine();
					    }
					    if (currentSzene.getAbsaetze()
						    .get(l).getAbsatzID()
						    .equals("Regieanweisung")) {
						Regieanweisung regieanweisung = (Regieanweisung) currentSzene
							.getAbsaetze().get(l);
						writer.write(regieanweisung
							.toString().trim());
					    } else {
						Rede rede = (Rede) currentSzene
							.getAbsaetze().get(l);
						writer.write(rede.toString()
							.trim());
					    }
					}
				    }

				    writer.newLine();
				    writer.write("!Szene");
				}
			    }

			    writer.newLine();
			    writer.write("!Aufzug");
			}
		    }

		    // Rollen eines Stueckes schreiben
		    if (!stuecke.get(i).getRollen().isEmpty()) {
			writer.newLine();
			writer.write("Rollen");
			writer.newLine();
			for (int j = 0; j < stuecke.get(i).getRollen().size(); j++) {
			    if (j > 0) {
				writer.newLine();
			    }
			    writer.write(stuecke.get(i).getRollen().get(j)
				    .toString().trim());
			}
			writer.newLine();
			writer.write("!Rollen");
		    }

		    writer.newLine();
		    writer.write("!Stueck");
		}
	    }
	    writer.newLine();
	    writer.write("!Stuecke");

	    // Personen
	    writer.newLine();
	    writer.write("Personen");
	    if (!personen.isEmpty()) {
		writer.newLine();
		for (int i = 0; i < personen.size(); i++) {
		    if (i > 0) {
			writer.newLine();
		    }
		    String string = personen.get(i).getName() + " "
			    + personen.get(i).getGeschlecht() + " "
			    + personen.get(i).getGebDatum() + " "
			    + personen.get(i).getWortzahlMerken() + " Woerter";
		    writer.write(string);
		}
	    }
	    writer.newLine();
	    writer.write("!Personen");

	    // Ensemble
	    writer.newLine();
	    writer.write("Ensembles");
	    if (!ensembles.isEmpty()) {
		writer.newLine();
		for (int i = 0; i < ensembles.size(); i++) {
		    if (i > 0) {
			writer.newLine();
		    }
		    writer.write("Ensemble");
		    writer.newLine();
		    // Name
		    writer.write("Bezeichnung");
		    writer.newLine();
		    writer.write(ensembles.get(i).getName().trim());
		    writer.newLine();
		    writer.write("!Bezeichnung");
		    writer.newLine();
		    // Personennamen schreiben
		    writer.write("Gruppe");
		    if (!ensembles.get(i).getGruppe().isEmpty()) {
			writer.newLine();
			for (int j = 0; j < ensembles.get(i).getGruppe().size(); j++) {
			    if (j > 0) {
				writer.newLine();
			    }
			    writer.write(ensembles.get(i).getGruppe().get(j)
				    .getName().trim());
			}
		    }
		    writer.newLine();
		    writer.write("!Gruppe");
		    writer.newLine();
		    writer.write("!Ensemble");
		}
	    }
	    writer.newLine();
	    writer.write("!Ensembles");

	    // Inszenierungen
	    writer.newLine();
	    writer.write("Inszenierungen");
	    if (!inszenierungen.isEmpty()) {
		writer.newLine();
		for (int i = 0; i < inszenierungen.size(); i++) {
		    if (i > 0) {
			writer.newLine();
		    }
		    writer.write("Inszenierung");
		    writer.newLine();
		    writer.write("InszBezeichnung");
		    writer.newLine();
		    writer.write(inszenierungen.get(i).getInszBezeichnung()
			    .trim());
		    writer.newLine();
		    writer.write("!InszBezeichnung");
		    writer.newLine();
		    writer.write("gewStueck");
		    writer.newLine();
		    writer.write(inszenierungen.get(i).getStueck().getName()
			    .trim());
		    writer.newLine();
		    writer.write("!gewStueck");
		    writer.newLine();
		    writer.write("gewEnsemble");
		    writer.newLine();
		    writer.write(inszenierungen.get(i).getEnsemble().getName()
			    .trim());
		    writer.newLine();
		    writer.write("!gewEnsemble");
		    writer.newLine();
		    writer.write("Darstellerposten");
		    if (!inszenierungen.get(i).getDarstellerPosten().isEmpty()) {
			writer.newLine();
			for (int j = 0; j < inszenierungen.get(i)
				.getDarstellerPosten().size(); j++) {
			    if (j > 0) {
				writer.newLine();
			    }
			    Darstellerposten d = inszenierungen.get(i)
				    .getDarstellerPosten().get(j);
			    String besetzung = d.getRolle().getRollenName()
				    + "-";
			    for (int k = 0; k < d.getBesetzung().size(); k++) {
				if (k > 0) {
				    besetzung += ",";
				}
				besetzung += d.getBesetzung().get(k).getName();
			    }
			    writer.write(besetzung.trim());
			}
		    }
		    writer.newLine();
		    writer.write("!Darstellerposten");
		    writer.newLine();
		    writer.write("Nichtdarstellerposten");
		    if (!inszenierungen.get(i).getNichtDarPosten().isEmpty()) {
			writer.newLine();
			for (int j = 0; j < inszenierungen.get(i)
				.getNichtDarPosten().size(); j++) {
			    if (j > 0) {
				writer.newLine();
			    }
			    Nichtdarstellerposten n = inszenierungen.get(i)
				    .getNichtDarPosten().get(j);
			    String besetzung = n.getBezeichnung() + "-";
			    for (int k = 0; k < n.getBesetzung().size(); k++) {
				if (k > 0) {
				    besetzung += ",";
				}
				besetzung += n.getBesetzung().get(k).getName();
			    }
			    writer.write(besetzung.trim());
			}
		    }
		    writer.newLine();
		    writer.write("!Nichtdarstellerposten");
		    writer.newLine();
		    writer.write("!Inszenierung");
		}
	    }
	    writer.newLine();
	    writer.write("!Inszenierungen");

	    writer.flush();
	    writer.close();
	} catch (IOException e) {
	    e.printStackTrace();
	}
	// entfernen der Sicherung
	if (!temp) {
	    System.out.println("test");
	    entferneSicherung();
	}
    }

    /**
     * Entfernen der Sicherungsdatei, sofern eine vorhanden ist; Die Datei wird
     * sofort geloescht (sie wird z.B. nicht in den Windows-Papierkorb
     * verschoben);
     */
    public void entferneSicherung() {
	String fileName = "Projekt.nnn.tmp";
	File file = new File(fileName);
	file.delete();
    }

    /**
     * @param path
     *            Diese Methode laedt eine durch dieses Programm erzeugte
     *            Projektdatei;
     */
    public void ladeProjekt(String path) {
	if (path != null) {

	    // Variable, die bei einer Exception anzeigen soll,
	    // wo genau der Lesefehler auftrat:
	    int counter = 1;

	    try {
		BufferedReader br = new BufferedReader(new InputStreamReader(
			new FileInputStream(path)));

		String zeile;
		String prev = "";

		int zustand = 0;
		// 0-> Suchen nach Stuecke, Personen, Ensemble, Inszenierung
		// 1->Stuecke, 11-> Stueck, 112->Titel, 113-> Akt, 1131->Szene
		// 114->Rollen, etc.

		// Initialisierung von Variablen:
		String titel = "";
		List<Akt> akte = new ArrayList<Akt>();
		List<Rolle> rollen = new ArrayList<Rolle>();
		String aktID = "";
		List<Szene> szenen = new ArrayList<Szene>();
		String szenenID = "";
		List<Absatz> absaetze = new ArrayList<Absatz>();
		String ensembleBezeichnung = "";
		List<String> gruppe = new ArrayList<String>();
		String inszBezeichnung = "";
		Stueck inszStueck = null;
		Ensemble inszEnsemble = null;
		List<Darstellerposten> darstellerposten = new ArrayList<Darstellerposten>();
		List<Person> besetzung = new ArrayList<Person>();
		List<Nichtdarstellerposten> nichtDarsteller = new ArrayList<Nichtdarstellerposten>();

		List<Person> besetzungNicht = new ArrayList<Person>();
		while ((zeile = br.readLine()) != null) {
		    if (zeile.equals("Stuecke") && zustand == 0) {
			zustand = 1;
		    } else if (zeile.equals("!Stuecke")) {
			zustand = 0;
		    } else if (zeile.equals("Stueck") && zustand == 1) {
			zustand = 11;
		    } else if (zeile.equals("!Stueck")) {
			// aktuelles Stueck ist beendet
			if (!titel.equals("") && !akte.isEmpty()
				&& !rollen.isEmpty()) {
			    Stueck neuesStueck = new Stueck(titel, akte, rollen);
			    fuegeStueckHinzu(neuesStueck);
			    // Objekte fuer neues Stueck leeren
			    titel = "";
			    akte.clear();
			    rollen.clear();
			}
			zustand = 1;
		    } else if (zeile.equals("Titel")) {
			zustand = 112;
		    } else if (zeile.equals("!Titel")) {
			zustand = 11;
		    } else if (zustand == 112 && !zeile.equals("Titel")) {
			titel = zeile;
		    } else if (zeile.equals("Aufzug")) {
			zustand = 113;
		    } else if (zeile.equals("!Aufzug")) {
			Akt neuerAkt = (new Akt(aktID, szenen)).tiefeKopie();
			akte.add(neuerAkt);
			zustand = 11;
			aktID = "";
			szenen.clear();
		    } else if (prev.equals("Aufzug")) {
			aktID = zeile;
			zustand = 1131;
		    } else if (zeile.equals("!Szene")) {
			Szene neueSzene = (new Szene(szenenID, rollen, absaetze))
				.tiefeKopie();
			szenen.add(neueSzene);
			szenenID = "";
			absaetze.clear();
			rollen.clear();
		    } else if (zustand == 1131 && !zeile.equals("Szene")) {
			if (zeile.contains("SCENE") && zeile.length() < 20) {
			    szenenID = zeile;
			} else if (zeile.contains("Regieanweisung")) {
			    String anweisung = zeile.substring(zeile
				    .indexOf(":") + 2);
			    Regieanweisung regieanweisung = new Regieanweisung(
				    "Regieanweisung", anweisung);
			    absaetze.add(regieanweisung);
			} else {
			    String rolle = zeile.substring(0,
				    zeile.indexOf(":"));
			    String text = zeile
				    .substring(zeile.indexOf(":") + 2);
			    Rede rede = new Rede("Redepassage", rolle,
				    new Text(text));
			    absaetze.add(rede);
			}
		    } else if (zeile.equals("Rollen")) {
			zustand = 114;
		    } else if (zeile.equals("!Rollen")) {
			zustand = 11;
		    } else if (zustand == 114 && !zeile.equals("Rollen")) {
			Rolle rolle = parseRolle(zeile);
			rollen.add(rolle);
		    }

		    // Personen laden
		    else if (zeile.equals("Personen") && zustand == 0) {
			zustand = 2;
		    } else if (zeile.equals("!Personen")) {
			zustand = 0;
		    } else if (zustand == 2 && !zeile.equals("Personen")) {
			personen.add(parsePerson(zeile));
		    }

		    // Ensemble laden
		    else if (zeile.equals("Ensembles") && zustand == 0) {
			zustand = 3;
		    } else if (zeile.equals("!Ensembles")) {
			zustand = 0;
		    } else if (zeile.equals("Ensemble") && zustand == 3) {
			zustand = 31;
		    } else if (zeile.equals("!Ensemble")) {
			// ein Ensemble ist beendet
			zustand = 3;
			if (!ensembleBezeichnung.isEmpty()) {
			    Ensemble ensemble = new Ensemble(
				    ensembleBezeichnung, getGruppe(gruppe));
			    ensembles.add(ensemble);
			    ensembleBezeichnung = "";
			    gruppe.clear();
			}
		    } else if (zeile.equals("Bezeichnung")) {
			zustand = 311;
		    } else if (zeile.equals("!Bezeichnung")) {
			zustand = 31;
		    } else if (zustand == 311 && !zeile.equals("Bezeichnung")) {
			ensembleBezeichnung = zeile;
		    } else if (zeile.equals("Gruppe")) {
			zustand = 312;
		    } else if (zeile.equals("!Gruppe")) {
			zustand = 31;
		    } else if (zustand == 312 && !zeile.equals("Gruppe")) {
			gruppe.add(zeile);
		    }
		    // Inszenierung laden
		    else if (zeile.equals("Inszenierungen") && zustand == 0) {
			zustand = 4;
		    } else if (zeile.equals("!Inszenierungen")) {
			zustand = 0;
		    } else if (zeile.equals("Inszenierung") && zustand == 4) {
			zustand = 41;
		    } else if (zeile.equals("!Inszenierung")) {
			// ein Inszenierung ist beendet
			zustand = 4;
			if (!inszBezeichnung.isEmpty()) {
			    Inszenierung insz = new Inszenierung(new String(
				    inszBezeichnung), inszStueck, inszEnsemble,
				    darstellerposten, nichtDarsteller);
			    inszenierungen.add(insz.tiefeKopie());
			    inszBezeichnung = "";
			    darstellerposten.clear();
			    nichtDarsteller.clear();
			}
		    } else if (zustand == 41 && prev.equals("gewStueck")) {
			for (int i = 0; i < stuecke.size(); i++) {
			    if (stuecke.get(i).getName().equals(zeile)) {
				inszStueck = stuecke.get(i);
			    }
			}
		    } else if (zustand == 41 && prev.equals("gewEnsemble")) {
			for (int i = 0; i < ensembles.size(); i++) {
			    if (ensembles.get(i).getName().equals(zeile)) {
				inszEnsemble = ensembles.get(i);
			    }
			}
		    } else if (zustand == 41 && prev.equals("InszBezeichnung")) {
			inszBezeichnung = zeile;
		    } else if (zustand == 41
			    && zeile.equals("Darstellerposten")) {
			zustand = 411;
		    } else if (zustand == 411
			    && zeile.equals("!Darstellerposten")) {
			zustand = 41;
		    } else if (zustand == 411) {
			Rolle rolle = null;
			String rollenName = zeile.substring(0,
				zeile.indexOf("-"));
			for (Rolle r : inszStueck.getRollen()) {
			    if (r.getRollenName().equals(rollenName)) {
				rolle = r;
				break;
			    }
			}
			String besetzungString = zeile.substring(zeile
				.indexOf("-") + 1);
			if (!besetzungString.contains(",")) {
			    // dann wurde nur eine Person zugewiesen;
			    besetzung.add(getPersonFromString(besetzungString));
			} else {
			    int zaehler = 0;
			    for (int i = 0; i < besetzungString.length(); i++) {
				if (String.valueOf(besetzungString.charAt(i))
					.equals(",")) {
				    zaehler++;
				}
			    }
			    if (zaehler == 1) {
				// dann wurden zwei Personen der Rolle
				// zugewiesen;
				besetzung
					.add(getPersonFromString(besetzungString
						.substring(0, besetzungString
							.indexOf(","))));
				besetzung
					.add(getPersonFromString(besetzungString
						.substring(besetzungString
							.indexOf(",") + 1)));
			    } else if (zaehler == 2) {
				// dann wurden drei Personen der Rolle
				// zugewiesen;
				besetzung
					.add(getPersonFromString(besetzungString
						.substring(0, besetzungString
							.indexOf(","))));
				String split = besetzungString
					.substring(besetzungString.indexOf(",") + 1);
				besetzung.add(getPersonFromString(split
					.substring(0, split.indexOf(","))));
				besetzung.add(getPersonFromString(split
					.substring(split.indexOf(",") + 1)));
			    }
			}
			darstellerposten.add(new Darstellerposten(rolle,
				besetzung).tiefeKopie());
			besetzung.clear();
		    } else if (zustand == 41
			    && zeile.equals("Nichtdarstellerposten")) {
			zustand = 412;
		    } else if (zustand == 412
			    && zeile.equals("!Nichtdarstellerposten")) {
			zustand = 41;
		    } else if (zustand == 412) {
			String bezeichnung = zeile.substring(0,
				zeile.indexOf("-"));
			String besetzungString = zeile.substring(zeile
				.indexOf("-") + 1);

			if (!besetzungString.contains(",")) {
			    // dann wurde nur eine Person zugewiesen;
			    besetzungNicht
				    .add(getPersonFromString(besetzungString));
			} else {
			    int zaehler = 0;
			    for (int i = 0; i < besetzungString.length(); i++) {
				if (String.valueOf(besetzungString.charAt(i))
					.equals(",")) {
				    zaehler++;
				}
			    }
			    if (zaehler == 1) {
				// dann wurden zwei Personen der Rolle
				// zugewiesen;
				besetzungNicht
					.add(getPersonFromString(besetzungString
						.substring(0, besetzungString
							.indexOf(","))));
				besetzungNicht
					.add(getPersonFromString(besetzungString
						.substring(besetzungString
							.indexOf(",") + 1)));
			    } else if (zaehler == 2) {
				// dann wurden drei Personen der Rolle
				// zugewiesen;
				besetzungNicht
					.add(getPersonFromString(besetzungString
						.substring(0, besetzungString
							.indexOf(","))));
				String split = besetzungString
					.substring(besetzungString.indexOf(",") + 1);
				besetzungNicht.add(getPersonFromString(split
					.substring(0, split.indexOf(","))));
				besetzungNicht.add(getPersonFromString(split
					.substring(split.indexOf(",") + 1)));
			    }
			}
			nichtDarsteller.add(new Nichtdarstellerposten(
				bezeichnung, besetzungNicht).tiefeKopie());
			besetzungNicht.clear();
		    }
		    prev = zeile;
		    counter++;
		}
		br.close();
	    } catch (FileNotFoundException e) {
		e.printStackTrace();
	    } catch (Exception e) {
		JOptionPane.showMessageDialog(null,
			new String("Fehler beim Laden der Datei - Zeile: "
				+ String.valueOf(counter)));
		e.printStackTrace();
	    }
	}
    }

    /**
     * @param namen
     * @return In der Projektdatei werden fuer ein Ensemble nur die Namen der
     *         Personen gespeichert; Hier werden nun die dazugehoerigen
     *         Personen-Instanzen in ein Array fuer das Ensemble geladen;
     */
    private List<Person> getGruppe(List<String> namen) {
	List<Person> gruppe = new ArrayList<Person>();
	if (gruppe != null && namen.size() > 0) {
	    for (String name : namen) {
		for (Person p : personen) {
		    if (name.equals(p.getName())) {
			gruppe.add(p);
		    }
		}
	    }
	}
	return gruppe;
    }

    /**
     * @param zeile
     * @return Die uebergebene Zeile ist nach folgendem Muster aufgebaut: "LADY
     *         MACBETH weiblich 44 ca: 780 Woerter" - Diese Methode parst das
     *         Rollen-Objekt aus dieser Zeilt;
     */
    private Rolle parseRolle(String zeile) {
	if (zeile != null) {
	    if (zeile.contains("maennlich")) {
		String rollenName = zeile.substring(0,
			zeile.indexOf("maennlich") - 1);
		String geschlecht = "maennlich";
		int alter = Integer.valueOf(zeile.substring(
			zeile.indexOf("maennlich") + 10,
			zeile.indexOf("ca") - 1));
		int textMenge = Integer
			.valueOf(zeile.substring(zeile.indexOf("ca:") + 4,
				zeile.indexOf("Woerter") - 1));
		Rolle rolle = new Rolle(rollenName, alter, geschlecht,
			textMenge);
		return rolle;
	    } else {
		String rollenName = zeile.substring(0,
			zeile.indexOf("weiblich") - 1);
		String geschlecht = "weiblich";
		int alter = Integer
			.valueOf(zeile.substring(zeile.indexOf("weiblich") + 9,
				zeile.indexOf("ca") - 1));
		int textMenge = Integer
			.valueOf(zeile.substring(zeile.indexOf("ca:") + 4,
				zeile.indexOf("Woerter") - 1));
		Rolle rolle = new Rolle(rollenName, alter, geschlecht,
			textMenge);
		return rolle;
	    }
	}
	return null;
    }

    /**
     * @param stueck
     *            Hinzufuegen vom uebergebenen Stueck zum Projekt, wobei der
     *            Titel des Theaterstueckes geaendert wird, falls dieser schon
     *            vorhanden ist;
     */
    public void fuegeStueckHinzu(Stueck stueck) {
	if (stueck != null) {
	    Stueck neuesStueck = stueck.tiefeKopie();
	    if (!stuecke.isEmpty()) {
		// Test, ob Stueck schon vorhanden ist
		for (int i = 0; i < stuecke.size(); i++) {
		    if (stuecke.get(i).getName().equals(neuesStueck.getName())) {
			if (neuesStueck.getName().contains("-Kopie")) {
			    // dann ist es schon eine Kopie; neue Version
			    // erstellen:
			    int start = neuesStueck.getName().lastIndexOf(
				    "-Kopie") + 6;
			    int version = Integer.valueOf(neuesStueck.getName()
				    .substring(start,
					    neuesStueck.getName().length()));
			    if (version > 0) {
				version++;
				String neuerName = neuesStueck.getName()
					.substring(0, start) + version;
				neuesStueck.setName(neuerName);
			    } else {
				String neuerName = neuesStueck.getName()
					+ "-Kopie1";
				neuesStueck.setName(neuerName);
			    }
			} else if (stuecke.get(i).getAkte().size() == stueck
				.getAkte().size()
				&& stuecke.get(i).getRollen().size() == stueck
					.getRollen().size()) {
			    // dann handelt es sich um dasselbe Stueck; Kopie
			    // erstellen:
			    String neuerName = neuesStueck.getName()
				    + "-Kopie1";
			    neuesStueck.setName(neuerName);
			} else {
			    // sonst wird es sich um zufaellige Namensgleichheit
			    // handeln;
			    String neuerName = neuesStueck.getName() + "-(1)";
			    neuesStueck.setName(neuerName);
			}
		    }
		}
		stuecke.add(neuesStueck);
	    } else {
		stuecke.add(neuesStueck);
	    }
	}
	fireListChanged();
    }

    /**
     * @param zeile
     * @return Analgo zur Methode parseRolle(String zeile);
     */
    public Person parsePerson(String zeile) {
	if (zeile != null) {
	    if (zeile.contains("maennlich")) {
		String name = zeile
			.substring(0, zeile.indexOf("maennlich") - 1);
		String geschlecht = "maennlich";
		String gebDatum = zeile.substring(
			zeile.indexOf("maennlich") + 10,
			zeile.indexOf("maennlich") + 20);
		int wortzahl = Integer.valueOf(zeile.substring(
			zeile.indexOf("maennlich") + 21,
			zeile.indexOf("Woerter") - 1));
		Person person = new Person(name, gebDatum, geschlecht, wortzahl);
		return person;
	    } else {
		String name = zeile.substring(0, zeile.indexOf("weiblich") - 1);
		String geschlecht = "weiblich";
		String gebDatum = zeile.substring(
			zeile.indexOf("weiblich") + 9,
			zeile.indexOf("weiblich") + 19);
		int wortzahl = Integer.valueOf(zeile.substring(
			zeile.indexOf("weiblich") + 20,
			zeile.indexOf("Woerter") - 1));
		Person person = new Person(name, gebDatum, geschlecht, wortzahl);
		return person;
	    }
	}
	return null;
    }

    public List<Ensemble> getEnsembles() {
	return ensembles;
    }

    public void setEnsembles(List<Ensemble> ensembles) {
	this.ensembles = ensembles;
    }

    /**
     * @param ensemble
     *            Analog zur Methode fuegeStueckHinzu(Stueck stueck);
     */
    public void fuegeEnsembleHinzu(Ensemble ensemble) {
	Ensemble neuesEnsemble = ensemble.tiefeKopie();
	if (!ensembles.isEmpty()) {
	    // Test, ob Ensemble schon vorhanden ist
	    for (int i = 0; i < ensembles.size(); i++) {
		if (ensembles.get(i).getName().equals(neuesEnsemble.getName())) {
		    if (neuesEnsemble.getName().contains("-")) {
			// dann ist es schon eine Kopie; neue Version
			int start = neuesEnsemble.getName().lastIndexOf("-") + 1;
			int version = Integer.valueOf(neuesEnsemble.getName()
				.substring(start,
					neuesEnsemble.getName().length()));
			if (version > 0) {
			    version++;
			    String neuerName = neuesEnsemble.getName()
				    .substring(0, start) + version;
			    neuesEnsemble.setName(neuerName);
			} else {
			    String neuerName = neuesEnsemble.getName() + "-1";
			    neuesEnsemble.setName(neuerName);
			}
		    } else {
			String neuerName = neuesEnsemble.getName() + "-1";
			neuesEnsemble.setName(neuerName);
		    }
		}
	    }
	    ensembles.add(neuesEnsemble);
	} else {
	    ensembles.add(neuesEnsemble);
	}
    }

    /**
     * @param inszenierung
     *            Analog zur Methode fuegeStueckHinzu(Stueck stueck);
     */
    public void fuegeInszenierungHinzu(Inszenierung inszenierung) {
	Inszenierung neueInszenierung = inszenierung.tiefeKopie();
	if (!inszenierungen.isEmpty()) {
	    // Test, ob Inszenierung schon vorhanden ist
	    for (int i = 0; i < inszenierungen.size(); i++) {
		if (inszenierungen.get(i).getInszBezeichnung()
			.equals(neueInszenierung.getInszBezeichnung())) {
		    if (neueInszenierung.getInszBezeichnung().contains("-")) {
			// dann ist es schon eine Kopie; neue Version
			int start = neueInszenierung.getInszBezeichnung()
				.lastIndexOf("-") + 1;
			int version = Integer.valueOf(neueInszenierung
				.getInszBezeichnung().substring(
					start,
					neueInszenierung.getInszBezeichnung()
						.length()));
			if (version > 0) {
			    version++;
			    String neueBez = neueInszenierung
				    .getInszBezeichnung().substring(0, start)
				    + version;
			    neueInszenierung.setInszBezeichnung(neueBez);
			} else {
			    String neuerName = neueInszenierung
				    .getInszBezeichnung() + "-1";
			    neueInszenierung.setInszBezeichnung(neuerName);
			}
		    } else {
			String neuerName = neueInszenierung
				.getInszBezeichnung() + "-1";
			neueInszenierung.setInszBezeichnung(neuerName);
		    }
		}
	    }
	    inszenierungen.add(neueInszenierung);
	} else {
	    inszenierungen.add(neueInszenierung);
	}
    }

    public void entferneInszenierung(String bezeichnung) {
	if (!inszenierungen.isEmpty()) {
	    for (int i = 0; i < inszenierungen.size(); i++) {
		if (inszenierungen.get(i).getInszBezeichnung()
			.equals(bezeichnung)) {
		    inszenierungen.remove(i);
		}
	    }
	}
    }

    public List<Inszenierung> getInszenierungen() {
	return inszenierungen;
    }

    public void setInszenierungen(List<Inszenierung> inszenierungen) {
	this.inszenierungen = inszenierungen;
    }

    /**
     * @param ensemble
     * @return Diese Methode prueft, ob das uebergebene Ensemble bei einer
     *         Inszenierung verwendet wird;
     */
    public boolean ensembleWirdVerwendet(Ensemble ensemble) {
	if (ensemble == null || inszenierungen.isEmpty()) {
	    return false;
	} else {
	    for (int i = 0; i < inszenierungen.size(); i++) {
		if (inszenierungen.get(i).getEnsemble().getName()
			.equals(ensemble.getName())) {
		    return true;
		}
	    }
	    return false;
	}
    }

    public void addListener(IMyListener l) {
	if (l != null) {
	    listeners.add(l);
	}
    }

    public void removeListener(IMyListener l) {
	if (l != null && listeners.contains(l)) {
	    listeners.remove(l);
	}
    }

    /**
     * Der Hauptdialog ShowGoDialog ist vom Typ IMyListener und wird
     * benachrichtigt, wenn diese Methode ausgefuehrt wird;
     */
    public void fireListChanged() {
	for (IMyListener l : listeners) {
	    l.listChanged();
	}
    }

    /**
     * @param name
     * @return Findet das entsprechende Personen-Objekt anhand des uebergebenen
     *         Namens;
     */
    public Person getPersonFromString(String name) {
	if (name != null) {
	    for (Person p : personen) {
		if (p.getName().equals(name)) {
		    return p;
		}
	    }
	}
	return null;
    }

    /**
     * @param rolle
     * @param stueck
     *            Entfernt die uebergebene Rolle aus dem uebergebenen Stueck und
     *            entfernt dabei alle dazugehoerigen Textpassagen;
     */
    public void entferneRolleAusStueck(Rolle rolle, Stueck stueck) {
	// Rolle aus dem uebergebenen Stueck entfernen
	stueck.getRollen().remove(rolle);

	// Textpassagen der Rolle aus dem Stueck entfernen
	for (Akt akt : stueck.getAkte()) {
	    for (Szene szene : akt.getSzenen()) {
		for (int i = 0; i < szene.getAbsaetze().size(); i++) {
		    if (szene.getAbsaetze().get(i).getAbsatzID()
			    .equals("Redepassage")) {
			Rede rede = (Rede) szene.getAbsaetze().get(i);
			if (rede.getRollenName().equals(rolle.getRollenName())) {
			    szene.getAbsaetze().remove(
				    szene.getAbsaetze().get(i));
			    i = 0;
			}
		    }
		}
	    }
	}

	// Jeder entsprechende Absatz wurde entfernt;
	// Wenn einzelne Szenen nun keine Absaeteze mehr haben,
	// werden sie aus dem Stueck entfernt;
	for (int j = 0; j < stueck.getAkte().size(); j++) {
	    for (int i = 0; i < stueck.getAkte().get(j).getSzenen().size(); i++) {
		if (stueck.getAkte().get(j).getSzenen().get(i).getAbsaetze()
			.isEmpty()) {
		    stueck.getAkte().get(j).getSzenen().remove(i);
		}
	    }
	    if (stueck.getAkte().get(j).getSzenen().isEmpty()) {
		stueck.getAkte().remove(j);
	    }
	}

	fireListChanged();
    }

    /**
     * @param rolle
     *            Die Rolle wird mit den dazugehoerigen Besetzungen aus der
     *            Inszenierung entfernt.
     */
    public void entferneRolleAusInszenierung(Rolle rolle, Stueck stueck) {
	// erst Rolle aus Stueck entfernen, sofern das nicht schon geschehen
	// ist:
	entferneRolleAusStueck(rolle, stueck);

	// dann die Inszenierung(en) finden, die das Stueck enthaelt:
	for (Inszenierung insz : inszenierungen) {
	    if (insz.getStueck().equals(stueck)) {
		// dann die entsprechenden Besetzungen entfernen:
		for (Darstellerposten d : insz.getDarstellerPosten()) {
		    if (d.getRolle().equals(rolle)) {
			insz.getDarstellerPosten().remove(d);
		    }
		}
	    }
	}
    }

    /**
     * @param rolle
     * @param stueck
     * @return Diese Methode prueft, ob die uebergebene Rolle noch im
     *         uebergebenen Stueck vorhanden ist;
     */
    public boolean rolleIstNochVorhanden(Rolle rolle, Stueck stueck) {
	for (Akt akt : stueck.getAkte()) {
	    for (Szene szene : akt.getSzenen()) {
		for (Absatz absatz : szene.getAbsaetze()) {
		    if (absatz.getAbsatzID().equals("Redepassage")) {
			Rede rede = (Rede) absatz;
			if (rede.getRollenName().equals(rolle.getRollenName())) {
			    return true;
			}
		    }
		}
	    }
	}
	return false;
    }

    /**
     * Hauptaufgabe der Methode ist zu pruefen, ob zu allen Besetzungen auch
     * noch die entsprechenden Rollen und Personen vorhanden sind; Ist dies
     * nicht mehr gewaehrt, wird die jeweilige Besetzung entfernt;
     */
    public void aktualisiereInszenierung() {
	for (Inszenierung insz : inszenierungen) {
	    if (!insz.getDarstellerPosten().isEmpty()) {
		for (int i = 0; i < insz.getDarstellerPosten().size(); i++) {
		    // erst pruefen, ob es die Rolle noch gibt:
		    Rolle rolle = insz.getDarstellerPosten().get(i).getRolle();
		    if (!rolleIstNochVorhanden(rolle, insz.getStueck())) {
			// dann den Posten entfernen:
			insz.getDarstellerPosten().remove(i);
			i = 0;
		    }
		    // dann pruefen, ob der Posten noch eine Besetzung hat:
		    if (insz.getDarstellerPosten().get(i).getBesetzung()
			    .isEmpty()) {
			insz.getDarstellerPosten().remove(i);
			i = 0;
		    }
		}
	    }
	}
    }

    /**
     * @param p
     * @param ensemble
     * @return Diese Methode prueft, ob die uebergebene Person noch im
     *         uebergebenen Ensemble ist;
     */
    public boolean personIstNochImEnsemble(Person p, Ensemble ensemble) {
	if (!ensemble.getGruppe().isEmpty()) {
	    for (Person person : ensemble.getGruppe()) {
		if (person.equals(p)) {
		    return true;
		}
	    }
	}
	return false;
    }

    public List<String> getNichtDarstellerPosten() {
	return nichtDarstellerPosten;
    }

    public void setNichtDarstellerPosten(List<String> nichtDarstellerPosten) {
	this.nichtDarstellerPosten = nichtDarstellerPosten;
    }
}
